package com.we823.cms.repository.service.sys;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.google.common.collect.Lists;
import com.we823.cms.common.web.pageable.Direction;
import com.we823.cms.common.web.pageable.Sort;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

import com.google.common.collect.Maps;
import com.we823.cms.model.sys.Resource;
import com.we823.cms.model.sys.ResourceType;
import com.we823.cms.repository.dao.sys.ResourceMapper;
import com.we823.cms.repository.service.AbstractBaseService;

@Service
@Scope("prototype")
public class ResourceService extends AbstractBaseService<Resource, Integer> {

	private ResourceMapper resourceMapper;
	
	@Autowired
	public ResourceService(ResourceMapper resourceMapper) {
		super(resourceMapper);
		this.resourceMapper = resourceMapper;
	}

	public Map<Integer, Resource> map(){
		List<Resource> resourceModels = findAll();
		if (resourceModels==null) return null;

		Map<Integer, Resource> map = Maps.newHashMap();
		for (Resource resourceModel : resourceModels) {
			map.put(resourceModel.getId(), resourceModel);
		}
		return map;
	}

	public List<Resource> findByParentid(int parentid, boolean containSubResource) {
		if (containSubResource) {
			Map<Integer, List<Resource>> parentResourceMap = getParentResourceMap(null); 
			if (parentResourceMap!=null) {
				List<Resource> resourceModels = parentResourceMap.get(parentid);
				fillSubresources(resourceModels,parentResourceMap);
				return resourceModels;
			}
			return null;
		}else {
			Resource resource = new Resource();
			resource.setParentid(parentid);
			setSortInfo(new Sort(Direction.ASC,"orderid"));
			return resourceMapper.select(resource);
		}
	}
	
	private void fillSubresources(List<Resource> resources,
			Map<Integer, List<Resource>> parentResourceMap) {
		if (resources!=null && resources.size()>0) {
			for (Resource resourceModel : resources) {
				List<Resource> subresources = parentResourceMap.get(resourceModel.getId());
				if (subresources!=null && subresources.size()>0) {
					fillSubresources(subresources, parentResourceMap);
				}
				resourceModel.setSubresources(subresources);
			}
		}
		
	}

	private Map<Integer, List<Resource>> getParentResourceMap(ResourceType type) {
		Sort sort = new Sort(Direction.ASC,"orderid");
		
		List<Resource> resourceModels = null;
		if (type==null) {
			resourceModels = findAll(sort);
		}else {
			Resource resource = new Resource();
			resource.setType(type);
			setSortInfo(sort);
			resourceModels = resourceMapper.select(resource);
		}
		
		if (resourceModels!=null && resourceModels.size()>0) {
			Map<Integer, List<Resource>> map = Maps.newHashMap();
			for (Resource resourceModel : resourceModels) {
				int parentid = resourceModel.getParentid();
				if (map.containsKey(parentid)) {
					map.get(parentid).add(resourceModel);
				}else {
					List<Resource> subResourceModels = Lists.newArrayList();
					subResourceModels.add(resourceModel);
					map.put(parentid, subResourceModels);
				}
			}
			return map;
		}
		return null;
	}


	public List<Resource> findByParentidAndType(int parentid, ResourceType type,
			boolean containSubResource) {
		if (containSubResource) {
			Map<Integer, List<Resource>> parentResourceMap = getParentResourceMap(type); 
			List<Resource> resourceModels = parentResourceMap.get(parentid);
			fillSubresources(resourceModels,parentResourceMap);
			return resourceModels;
		}else {
			Resource resource = new Resource();
			resource.setParentid(parentid);
			resource.setType(type);
			setSortInfo(new Sort(Direction.ASC,"orderid"));
			return resourceMapper.select(resource);
		}
	}
}
